package org.gikolet.ch2.android.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.input.CountingInputStream;
import org.gikolet.ch2.data.Board;
import org.gikolet.ch2.data.Category;
import org.gikolet.ch2.io.BoardsReader;
import org.gikolet.util.Tuple.Tuple2;

public class KatjushaBoardsStreamParser implements BoardsReader {

	private static final String TAB = "\t";

	private BufferedReader reader;

	private CountingInputStream countIn;

	private String nowCategory;

	public KatjushaBoardsStreamParser(InputStream in, String charsetName)
			throws IOException {
		this(in, Charset.forName(charsetName));
	}

	public KatjushaBoardsStreamParser(InputStream in, Charset charset)
			throws IOException {
		this.countIn = new CountingInputStream(in);
		this.reader = new BufferedReader(new InputStreamReader(this.countIn,
				charset));

		// 最初を読み飛ばし
		this.reader.readLine();
	}

	public Tuple2<Category, List<Board>> read() throws IOException {
		String line = this.reader.readLine();
		if (line == null) {
			return null;
		}

		String category = this.nowCategory;
		if (category == null) {
			String[] values = line.split(TAB);
			if (values.length != 2) {
				throw new IOException();
			}

			category = values[0];
			this.nowCategory = category;

			line = this.reader.readLine();
		}

		List<Board> boards = new ArrayList<Board>();

		while (line != null) {

			String[] values = line.split(TAB);
			if (values.length == 2) {
				this.nowCategory = values[0];
				break;

			} else if (values.length == 4) {
				Board board = new Board(values[1], values[2], values[3]);
				boards.add(board);

			} else {
				throw new IOException("Format is invalid.");
			}

			line = this.reader.readLine();
		}

		return new Tuple2<Category, List<Board>>(new Category(category), boards);
	}

	public void close() throws IOException {
		this.reader.close();
	}

	public long getContentLength() {
		return -1;
	}

	public long getReadContentLength() {
		return this.countIn.getByteCount();
	}
}
